home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 1999 #2 / Amiga Plus CD - 1999 - No. 2.iso / System-Boost / Workbench / ToolManager / Source / Prefs / droparea.c < prev    next >
C/C++ Source or Header  |  1998-06-17  |  10KB  |  371 lines

  1. /*
  2.  * droparea.c  V3.1
  3.  *
  4.  * Class to drop TM objects on
  5.  *
  6.  * Copyright (C) 1990-98 Stefan Becker
  7.  *
  8.  * This source code is for educational purposes only. You may study it
  9.  * and copy ideas or algorithms from it for your own projects. It is
  10.  * not allowed to use any of the source codes (in full or in parts)
  11.  * in other programs. Especially it is not allowed to create variants
  12.  * of ToolManager or ToolManager-like programs from this source code.
  13.  *
  14.  */
  15.  
  16. #include "toolmanager.h"
  17.  
  18. /* DropArea class instance data */
  19. struct DropAreaClassData {
  20.  ULONG              dacd_Type;
  21.  struct AttachData *dacd_Data;
  22. };
  23. #define TYPED_INST_DATA(cl, o) ((struct DropAreaClassData *) INST_DATA((cl), (o)))
  24.  
  25. /* DropArea class method: OM_NEW */
  26. #define DEBUGFUNCTION DropAreaClassNew
  27. static ULONG DropAreaClassNew(Class *cl, Object *obj, struct opSet *ops)
  28. {
  29.  DROPAREA_LOG((LOG1(Tags, "0x%08lx", ops->ops_AttrList),
  30.                     PrintTagList(ops->ops_AttrList)))
  31.  
  32.  /* Create object */
  33.  if (obj = (Object *) DoSuperNew(cl, obj,
  34.                                     MUIA_Text_SetMin, TRUE,
  35.                                     MUIA_Background,  MUII_TextBack,
  36.                                     MUIA_Dropable,    TRUE,
  37.                                     MUIA_InputMode,   MUIV_InputMode_RelVerify,
  38.                                     TextFrame,
  39.                                     TAG_MORE,         ops->ops_AttrList)) {
  40.   struct DropAreaClassData *dacd = TYPED_INST_DATA(cl, obj);
  41.   struct AttachData        *old  = (struct AttachData *)
  42.                                     GetTagData(TMA_Attach, NULL,
  43.                                                ops->ops_AttrList);
  44.  
  45.   /* Initialize instance data */
  46.   dacd->dacd_Type = GetTagData(TMA_Type, 0, ops->ops_AttrList);
  47.   dacd->dacd_Data = NULL;
  48.  
  49.   /* Old attach data valid? */
  50.   if (old) {
  51.  
  52.    DROPAREA_LOG(LOG1(Attaching, "0x%08lx", old->ad_Object))
  53.  
  54.    /* Yes, attach to object */
  55.    if (dacd->dacd_Data = (struct AttachData *)
  56.                           DoMethod(old->ad_Object, TMM_Attach, obj)) {
  57.  
  58.     DROPAREA_LOG(LOG0(Attached to object))
  59.  
  60.     /* Set initial text contents */
  61.     DoMethod(obj, TMM_Notify, dacd->dacd_Data);
  62.  
  63.     /* "Button" action */
  64.     DoMethod(obj, MUIM_Notify, MUIA_Pressed, FALSE,
  65.              obj, 1, TMM_DoubleClicked);
  66.  
  67.    } else {
  68.  
  69.     DROPAREA_LOG(LOG0(Could not attach object))
  70.  
  71.     /* Delete object again */
  72.     CoerceMethod(cl, obj, OM_DISPOSE);
  73.  
  74.     /* Reset object pointer */
  75.     obj = NULL;
  76.    }
  77.   }
  78.  }
  79.  
  80.  DROPAREA_LOG(LOG1(Result, "0x%08lx", obj))
  81.  
  82.  /* Return pointer to created object */
  83.  return((ULONG) obj);
  84. }
  85.  
  86. /* DropArea class method: OM_DISPOSE */
  87. #undef  DEBUGFUNCTION
  88. #define DEBUGFUNCTION DropAreaClassDispose
  89. static ULONG DropAreaClassDispose(Class *cl, Object *obj, Msg msg)
  90. {
  91.  struct DropAreaClassData *dacd = TYPED_INST_DATA(cl, obj);
  92.  
  93.  DROPAREA_LOG(LOG1(Disposing, "0x%08lx", obj))
  94.  
  95.  /* Detach object */
  96.  if (dacd->dacd_Data) DoMethod(dacd->dacd_Data->ad_Object, TMM_Detach,
  97.                                dacd->dacd_Data);
  98.  
  99.  /* Call SuperClass */
  100.  return(DoSuperMethodA(cl, obj, msg));
  101. }
  102.  
  103. /* Base class method: OM_SET */
  104. #undef  DEBUGFUNCTION
  105. #define DEBUGFUNCTION DropAreaClassSet
  106. static ULONG DropAreaClassSet(Class *cl, Object *obj, struct opSet *ops)
  107. {
  108.  struct TagItem *tstate = ops->ops_AttrList;
  109.  struct TagItem *ti;
  110.  
  111.  DROPAREA_LOG((LOG1(Tags, "0x%08lx", ops->ops_AttrList),
  112.                PrintTagList(ops->ops_AttrList)))
  113.  
  114.  /* Scan tag list */
  115.  while (ti = NextTagItem(&tstate))
  116.  
  117.   /* Which attribute shall be set? */
  118.   switch (ti->ti_Tag) {
  119.    case TMA_Object: {
  120.      struct AttachData *new;
  121.  
  122.      /* Attach to new object */
  123.      if (new = (struct AttachData *) DoMethod((Object *) ti->ti_Data,
  124.                                               TMM_Attach, obj)) {
  125.       struct DropAreaClassData *dacd = TYPED_INST_DATA(cl, obj);
  126.  
  127.       DROPAREA_LOG(LOG1(Attach, "0x%08lx", new))
  128.  
  129.       /* Detach old object */
  130.       if (dacd->dacd_Data) DoMethod(dacd->dacd_Data->ad_Object, TMM_Detach,
  131.                                     dacd->dacd_Data);
  132.  
  133.       /* Set new object */
  134.       dacd->dacd_Data = new;
  135.  
  136.       /* Update contents */
  137.       DoMethod(obj, TMM_Notify, new);
  138.      }
  139.     }
  140.     break;
  141.   }
  142.  
  143.  /* Call SuperClass */
  144.  return(DoSuperMethodA(cl, obj, (Msg) ops));
  145. }
  146.  
  147. /* DropArea class method: OM_GET */
  148. #undef  DEBUGFUNCTION
  149. #define DEBUGFUNCTION DropAreaClassGet
  150. static ULONG DropAreaClassGet(Class *cl, Object *obj, struct opGet *opg)
  151. {
  152.  ULONG rc;
  153.  
  154.  DROPAREA_LOG(LOG2(Attribute, "0x%08lx (%s)", opg->opg_AttrID,
  155.                    GetTagName(opg->opg_AttrID)))
  156.  
  157.  /* Which attribute is requested? */
  158.  switch(opg->opg_AttrID) {
  159.   case TMA_Attach:
  160.    *opg->opg_Storage = (ULONG) TYPED_INST_DATA(cl, obj)->dacd_Data;
  161.  
  162.    /* Return TRUE to indicate that the attribute is implemented */
  163.    rc = TRUE;
  164.    break;
  165.  
  166.   default:
  167.    rc = DoSuperMethodA(cl, obj, (Msg) opg);
  168.    break;
  169.  }
  170.  
  171.  DROPAREA_LOG(LOG2(Result, "%ld value 0x%08lx", rc, *opg->opg_Storage))
  172.  
  173.  return(rc);
  174. }
  175.  
  176. /* DropArea class method: MUIM_DragQuery */
  177. #undef  DEBUGFUNCTION
  178. #define DEBUGFUNCTION DropAreaClassDragQuery
  179. static ULONG DropAreaClassDragQuery(Class *cl, Object *obj,
  180.                                     struct MUIP_DragQuery *mpdq)
  181. {
  182.  Object *src;
  183.  ULONG   type = TMOBJTYPES;
  184.  
  185. #if DEBUG_VERY_NOISY
  186.  /* This just generates too much debug output... */
  187.  DROPAREA_LOG(LOG1(Arguments, "Source 0x%08lx", mpdq->obj))
  188. #endif
  189.  
  190.  /* Ask source object for active tree node */
  191.  if (GetAttr(TMA_Active, mpdq->obj, (ULONG *) &src))
  192.  
  193.   /* Get object type */
  194.   GetAttr(TMA_Type, src, &type);
  195.  
  196.  /* Is the type allowed? */
  197.  return((TYPED_INST_DATA(cl, obj)->dacd_Type == type) ?
  198.          MUIV_DragQuery_Accept : MUIV_DragQuery_Refuse);
  199. }
  200.  
  201. /* DropArea class method: MUIM_DragDrop */
  202. #undef  DEBUGFUNCTION
  203. #define DEBUGFUNCTION DropAreaClassDragDrop
  204. static ULONG DropAreaClassDragDrop(Class *cl, Object *obj,
  205.                                    struct MUIP_DragDrop *mpdd)
  206. {
  207.  Object            *src;
  208.  struct AttachData *ad;
  209.  
  210. #if DEBUG_VERY_NOISY
  211.  /* This just generates too much debug output... */
  212.  DROPAREA_LOG(LOG1(Arguments, "Source 0x%08lx", mpdd->obj))
  213. #endif
  214.  
  215.  /* Ask source object for active tree node */
  216.  GetAttr(TMA_Active, mpdd->obj, (ULONG *) &src);
  217.  
  218.  /* Attach to object */
  219.  if (ad = (struct AttachData *) DoMethod(src, TMM_Attach, obj)) {
  220.   struct DropAreaClassData *dacd = TYPED_INST_DATA(cl, obj);
  221.  
  222.   /* Detach old object */
  223.   if (dacd->dacd_Data) DoMethod(dacd->dacd_Data->ad_Object, TMM_Detach,
  224.                                 dacd->dacd_Data);
  225.  
  226.   /* Set new object */
  227.   dacd->dacd_Data = ad;
  228.  
  229.   /* Update contents */
  230.   DoMethod(obj, TMM_Notify, ad);
  231.  }
  232.  
  233.  /* Return 1 to indicate that the method is implemented */
  234.  return(1);
  235. }
  236.  
  237. /* DropArea class method: TMM_Notify */
  238. #undef  DEBUGFUNCTION
  239. #define DEBUGFUNCTION DropAreaClassNotify
  240. static ULONG DropAreaClassNotify(Class *cl, Object *obj,
  241.                                  struct TMP_Notify *tmpn)
  242. {
  243.  const char *name;
  244.  
  245.  DROPAREA_LOG(LOG1(Object, "0x%08lx", tmpn->tmpn_Data->ad_Object))
  246.  
  247.  /* Object valid? */
  248.  if (tmpn->tmpn_Data->ad_Object) {
  249.  
  250.   /* Yes, get new object name */
  251.   GetAttr(TMA_Name, tmpn->tmpn_Data->ad_Object, (ULONG *) &name);
  252.  
  253.   DROPAREA_LOG(LOG2(New Name, "%s (0x%08lx)", name, name))
  254.  
  255.  } else {
  256.   struct DropAreaClassData *dacd = TYPED_INST_DATA(cl, obj);
  257.  
  258.   DROPAREA_LOG(LOG0(Object has been deleted))
  259.  
  260.   /* Reset data pointer */
  261.   dacd->dacd_Data = NULL;
  262.  
  263.   /* No name */
  264.   name = NULL;
  265.  }
  266.  
  267.  /* Set new text contents */
  268.  SetAttrs(obj, MUIA_Text_Contents, name, TAG_DONE);
  269.  
  270.  /* Return 1 to indicate that the method is implemented */
  271.  return(1);
  272. }
  273.  
  274. /* DropArea class method: TMM_DoubleClicked */
  275. #undef  DEBUGFUNCTION
  276. #define DEBUGFUNCTION DropAreaClassDoubleClicked
  277. static ULONG DropAreaClassDoubleClicked(Class *cl, Object *obj)
  278. {
  279.  struct AttachData *ad;
  280.  
  281.  DROPAREA_LOG(LOG0(Entry))
  282.  
  283.  /* Object attached? */
  284.  if (ad = TYPED_INST_DATA(cl, obj)->dacd_Data) {
  285.  
  286.   DROPAREA_LOG(LOG1(Attach, "0x%08lx", ad))
  287.  
  288.   /* Yes, all Edit method on the object */
  289.   DoMethod(ad->ad_Object, TMM_Edit, NULL);
  290.  }
  291.  
  292.  /* Return 1 to indicate that the method is implemented */
  293.  return(1);
  294. }
  295.  
  296. /* DropArea class method dispatcher */
  297. #undef  DEBUGFUNCTION
  298. #define DEBUGFUNCTION DropAreaClassDispatcher
  299. __geta4 static ULONG DropAreaClassDispatcher(__a0 Class *cl, __a2 Object *obj,
  300.                                              __a1 Msg msg)
  301. {
  302.  ULONG rc;
  303.  
  304.  DROPAREA_LOG(LOG3(Arguments, "Class 0x%08lx Object 0x%08lx Msg 0x%08lx",
  305.                 cl, obj, msg))
  306.  
  307.  switch(msg->MethodID) {
  308.   /* BOOPSI methods */
  309.   case OM_NEW:
  310.    rc = DropAreaClassNew(cl, obj, (struct opSet *) msg);
  311.    break;
  312.  
  313.   case OM_DISPOSE:
  314.    rc = DropAreaClassDispose(cl, obj, msg);
  315.    break;
  316.  
  317.   case OM_SET:
  318.    rc = DropAreaClassSet(cl, obj, (struct opSet *) msg);
  319.    break;
  320.  
  321.   case OM_GET:
  322.    rc = DropAreaClassGet(cl, obj, (struct opGet *) msg);
  323.    break;
  324.  
  325.   /* MUI methods */
  326.   case MUIM_DragQuery:
  327.    rc = DropAreaClassDragQuery(cl, obj, (struct MUIP_DragQuery *) msg);
  328.    break;
  329.  
  330.   case MUIM_DragDrop:
  331.    rc = DropAreaClassDragDrop(cl, obj, (struct MUIP_DragDrop *) msg);
  332.    break;
  333.  
  334.   /* TM methods */
  335.   case TMM_Notify:
  336.    rc = DropAreaClassNotify(cl, obj, (struct TMP_Notify *) msg);
  337.    break;
  338.  
  339.   case TMM_DoubleClicked:
  340.    rc = DropAreaClassDoubleClicked(cl, obj);
  341.    break;
  342.  
  343.   /* Unknown method -> delegate to SuperClass */
  344.   default:
  345.    rc = DoSuperMethodA(cl, obj, msg);
  346.    break;
  347.  }
  348.  
  349.  return(rc);
  350. }
  351.  
  352. /* Create DropArea class */
  353. #undef  DEBUGFUNCTION
  354. #define DEBUGFUNCTION CreateDropAreaClass
  355. struct MUI_CustomClass *CreateDropAreaClass(void)
  356. {
  357.  struct MUI_CustomClass *rc;
  358.  
  359.  /* Create class */
  360.  if (rc = MUI_CreateCustomClass(NULL, MUIC_Text, NULL,
  361.                                 sizeof(struct DropAreaClassData),
  362.                                 DropAreaClassDispatcher)) {
  363.  
  364.   /* NOTHING TO DO */
  365.  }
  366.  
  367.  DROPAREA_LOG(LOG1(Result, "0x%08lx", rc))
  368.  
  369.  return(rc);
  370. }
  371.